<?php

function cf_numeric($html) {
	if (preg_match('/[0-9,\.]+/', $html, $out)) {
		return $out[0];
	}
	return '';
}

function cf_url($html) {
	if (preg_match_all('/<a[^>]*href=[\'"]?([^>\'"\s]*)[\'"]?[^>]*>/i', $html, $out)) {
		return implode('|', $out[1]);
	}
	return '';
}

function cf_image($html) {
	if (preg_match_all('/<img[^>]*src=[\'"]?([^>\'"\s]*)[\'"]?[^>]*>/i', $html, $out)) {
		return implode('|', $out[1]);
	}
	return '';
}

class Collection {
	protected static $url,$config, $data;
	protected static $funs = array(
			'strip_tags' => '去掉html标签',
			'cf_numeric'    => '提取数值',
			'cf_url'        => '提取链接地址',
			'cf_image'      => '提取图片地址'
	);
	
	/**
	 * 采集内容
	 * @param string $url    采集地址
	 * @param array $config  配置参数
	 */
	public static function get_content($url, &$config) {
		set_time_limit(300);
		static $oldurl = array();
		$data = array('name' => '', 'sku' => '', 'price' => '',
				'weight' => '', 'image' => '', 'description' => '',
				'other1' =>'', 'other2' => '', 'other3' => '');
		if ($html = self::get_html($url, $config)) {
			foreach ($data as $key => $val) {
				if ($config["{$key}_rule"]) {
					$rule = self::replace_sg($config["{$key}_rule"]);
					$data[$key] = self::replace_item(self::cut_html($html, $rule[0], $rule[1]), $config["{$key}_filter"]);
					if ($config["{$key}_func"]) {
						$funcs = explode('|', $config["{$key}_func"]);
						foreach ($funcs as $func) {
							if (array_key_exists($func, self::$funs)) {
								$data[$key] = $func($data[$key]);
							}
							elseif (is_file(DIR_APPLICATION . 'controller/tool/cf/' . $func . '.php')) {
								require_once(DIR_APPLICATION . 'controller/tool/cf/' . $func . '.php');
								$func .= "_{$key}";
								if (function_exists($func)) {
									$data[$key] = $func($data[$key], $config, $url);
								}
							}
						}
					}
				}
			}
			
			self::$url = $url;
			self::$config = $config;
			self::$data = &$data;
			//内容中的图片地址转为绝对地址
			$data['description'] = preg_replace('/<img[^>]*src=[\'"]?([^>\'"\s]*)[\'"]?[^>]*>/ie', "self::img_url('$0', '$1')", $data['description']);
			return $data;
		}
	}
	
	/**
	 * 转换图片地址为绝对路径，为下载做准备
	 */
	protected static function img_url($old, $out) {
		$old = stripslashes($old);
		self::$data['image'] = 1;
		if (!empty($old) && !empty($out) && strpos($out, '://') === false) {
			
			return str_replace($out, self::url_check($out, self::$url, self::$config['page_base'], self::$config['page_base_replace']), $old);
		} else {
			return $old;
		}
	}
	
	/**
	 * 得到需要采集的网页列表页
	 * @param array $config 配置参数
	 */
	public static function url_list(&$config) {
		$urls = array();
		$temp = explode("\r\n", $config['page_url']);
		foreach($temp as $url) {
			if($url) {
				if (strpos($url, '(*)') !== FALSE) {
					for ($i = $config['pageno_start']; $i <= $config['pageno_end']; $i++) {
						$urls[] = str_replace('(*)', $i, $url);
					}
				}
				else $urls[] = $url;
			}
		}
		return $urls;
	}
	
	/**
	 * 获取文章网址
	 * @param string $url           采集地址
	 * @param array $config         配置
	 */
	public static function get_url_lists($url, &$config) {
		if ($html = self::get_html($url, $config)) {
			$html = self::cut_html($html, $config['url_start'], $config['url_end']);
			$html = str_replace(array("\r", "\n"), '', $html);
			$html = str_replace(array("</a>", "</A>"), "</a>\n", $html);
			preg_match_all('/<a([^>]*)>([^\/a>].*)<\/a>/i', $html, $out);
			$out[1] = array_unique($out[1]);
			$out[2] = array_unique($out[2]);
			$data = array();
			$url_md5 = array();
			foreach ($out[1] as $k=>$v) {
				if (preg_match('/href=[\'"]?([^\'" ]*)[\'"]?/i', $v, $match_out)) {
					if ($config['url_contain']) {
						// if (strpos($match_out[1], $config['url_contain']) === false) {
						// continue;
						// }
						if (!preg_match('/'.str_replace('/', '\/', $config['url_contain']).'/i', $match_out[1])) continue;
					}
					
					if ($config['url_except']) {
						//if (strpos($match_out[1], $config['url_except']) !== false) {
						//	continue;
						//}
						if (preg_match('/'.str_replace('/', '\/', $config['url_except']).'/i', $match_out[1])) continue;
					}
					$url2 = $match_out[1];
					$url2 = self::url_check($url2, $url, $config['list_base'], $config['list_base_replace']);
					$md5 = md5($url2);
					$data[$k]['url'] = $url2;
					$data[$k]['urlmd5'] = $md5;
					$data[$k]['name'] = isset($out[2][$k]) ? trim(strip_tags($out[2][$k])) : '';
					$url_md5[$md5][] = $k;
				} else {
					continue;
				}
			}
			//过滤掉重复的URL
			foreach($url_md5 as $md5 => $keys) {
				if (count($keys) > 1) {
					$select = $keys[0];
					foreach($keys as $key) {
						if (!empty($data[$key]['name'])) {
							$select = $key;
							break;
						}
					}
					foreach($keys as $key) {
						if ($key != $select) unset($data[$key]);
					}
				}
			}
			return $data;
		} else {
			return false;
		}
	}
	
	/**
	 * 获取远程HTML
	 * @param string $url    获取地址
	 * @param array $config  配置
	 */
	public static function get_html($url, &$config) {
		if (!empty($url)) {
			if (!empty($config['use_curl']) && function_exists('curl_init')) {
				$ch = curl_init();
				curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 5.1; rv:14.0) Gecko/20100101 Firefox/14.0.1');
				$urlinfo = parse_url($url);
				$headers = array(
				'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
				'Cache-Control: max-age=0',
				'Connection: keep-alive',
				'Accept-Language: en-us,en;q=0.5',
				'Host: ' . $urlinfo['host'],
				);
				curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
				curl_setopt($ch, CURLOPT_REFERER, $config['referer'] ? $config['referer'] : $url);
				curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
				curl_setopt($ch, CURLOPT_URL, $url);
				$html = curl_exec($ch);
				curl_close($ch);
			}
			else  {
				$ctx = stream_context_create(
				array(
				'http' => array('timeout' => 30) //设置一个超时时间，单位为秒
				)
				);
				$html = file_get_contents($url, 0, $ctx);
			}
			if(!$html) return false;
			$page_charset = strtolower($config['page_charset']);
			if ('utf-8' != $page_charset && 'iso-8859-1' != $page_charset) {
				$html = iconv($config['page_charset'], 'utf-8//IGNORE', $html);
			}
			return $html;
		} else {
			return false;
		}
	}
	
	/**
		*
	 * HTML切取
	 * @param string $html    要进入切取的HTML代码
	 * @param string $start   开始
	 * @param string $end     结束
	 */
	public static function cut_html($html, $start, $end) {
		if (empty($html)) return false;
		$html = str_replace(array("\r", "\n"), "", $html);
		$start = str_replace(array("\r", "\n"), "", $start);
		$end = str_replace(array("\r", "\n"), "", $end);
		$html = explode(trim($start), $html, 2);
		if(is_array($html) && count($html) == 1) return false;//没有匹配
		$html = explode(trim($end), $html[1], 2);
		if(count($html) == 1) return false;
		return trim($html[0]);
	}
	
	/**
	 * 过滤代码
	 * @param string $html  HTML代码
	 * @param array $filters 过滤配置
	 */
	protected static function replace_item($html, $filters) {
		if (empty($filters)) return $html;
		$filters = explode("\n", $filters);
		$patterns = $replace = array();
		$p = 0;
		foreach ($filters as $k=>$v) {
			if (empty($v)) continue;
			$c = explode('[|]', $v);
			$patterns[$k] = '/'.str_replace('/', '\/', $c[0]).'/i';
			$replace[$k] = $c[1];
			$p = 1;
		}
		return $p ? @preg_replace($patterns, $replace, $html) : false;
	}
	
	/**
	 * 替换采集内容
	 * @param $html 采集规则
	 */
	protected static function replace_sg($html) {
		$list = explode('[content]', $html);
		if (is_array($list)) foreach ($list as $k=>$v) {
			$list[$k] = str_replace(array("\r", "\n"), '', trim($v));
		}
		return $list;
	}
	
	/**
	 * URL地址检查
	 * @param string $url     需要检查的URL
	 * @param string $cururl  当前访问页面的URL
	 * @param string $base    基本URL
	 * @param int replace 是否用base替换前缀
	 */
	public static function url_check($url, $cururl, $base = null, $replace = 0) {
		$urlinfo = parse_url($cururl);
		$cururl = $urlinfo['scheme'].'://'.$urlinfo['host'];
		$cururl .= str_replace('//', '/', str_replace(array('\\'), '/', dirname($urlinfo['path'])).'/');
		if (strpos($url, '://') === false) {
			if ($base) {
				$url = $base . $url;
			}
			elseif ($url[0] == '/') {
				$url = $urlinfo['scheme'].'://'.$urlinfo['host'].$url;
			} else {
				$url = $cururl.$url;
			}
		}
		//替换前缀
		if ($replace) {
			$urlinfo = parse_url($url);
			$url = str_replace($urlinfo['host'], $base, $url);
		}
		return $url;
	}
	
	public static function functions($name, $selected = null) {
		static $fun_files = array();

		if (empty($fun_files)) {
			$files = glob(DIR_APPLICATION . 'controller/tool/cf/*.php');
			if ($files) {
				foreach ($files as $file) {
					$fun_files[] = str_replace('.php', '', basename($file));
				}
			}
		}
		
		if ($selected) $selected = explode('|', $selected);
		$html = '';
		foreach (self::$funs as $fun => $label){
			$checked = (is_array($selected) && in_array($fun, $selected)) ? true : false;
			$html .= "<input type='checkbox' name='{$name}[]' value='{$fun}'" . ($checked ? " checked='checked'" : '') . "> {$label}<br>";
		}
		if ($fun_files) {
			$html .= "<br><select name='custom_$name'><option value=''>自定义函数</option>";
			foreach($fun_files as $v) {
				$s = (is_array($selected) && in_array($v, $selected)) ? true : false;
				$html .= "<option value='$v'" . ($s ? ' selected' : '') . ">$v</option>";
			}
			$html .= "</select>";
		}
		
		return $html;
	}
}